home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- VGLKEY.C
-
- This module supplies two functions. The first turns on an int 9 handler
- that allows you to test for multiple keys being held down, very useful in
- a game situation! The second function simply restores the original int 9
- handler.
-
- Mark
- morley@camosun.bc.ca
- *****************************************************************************/
-
- #include <dos.h>
- #include "vgl.h"
-
- struct KEYMAP /* This holds a list of key scan */
- { /* codes that we want to trap. */
- unsigned char downcode; /* Code when key is pressed */
- unsigned char upcode; /* Code when key is released */
- }
- Keys[VGL_NUMKEYS] = /* Add keys here!!! */
- {
- VGL_UPARROW,
- VGL_DOWNARROW,
- VGL_LEFTARROW,
- VGL_RIGHTARROW
- };
-
- char vglKeyStatus[VGL_NUMKEYS]; /* An array to hold key status */
- /* info. One byte per key defined */
- /* above. If a key is currently */
- /* being held down, its byte in */
- /* this list will be decimal 1, */
- /* otherwise it will be a 0. The */
- /* first key in the list above */
- /* maps to vglKeyStatus[0], the */
- /* second to vglKeyStatus[1], etc */
-
- static void interrupt (*oldint1b)();
- static void interrupt (*oldint23)();
- static void interrupt (*oldint9)(); /* Old int 9 handler */
-
- static int NumLock; /* Used to remember if NumLock was */
- /* active when we started. */
-
- /* Pointer to shift status area */
- static unsigned char far* kbdata = (unsigned char far*) MK_FP( 0x40, 0x17 );
-
- /* Macro to acknowledge a keystroke*/
- #define ACKKEY al = ah = inportb( 0x61 ); \
- al |= 0x80; \
- outportb( 0x61, al ); \
- outportb( 0x61, ah ); \
- outportb( 0x20, 0x20 )
-
- void interrupt int1b( void ) {}
- void interrupt int23( void ) {}
-
- /*****************************************************************************
- The int 9 handler. This routine fires everytime a key is pressed or
- released on the keyboard. Since each key generates a unique (more or less)
- scan code both when it's pressed, and a different one when it's released,
- we can actually have multiple keys being held down simultaneously.
-
- This routine simple loops through the list you define above, checking the
- current scan code against the up and down codes. If it matches one, then
- it sets or resets the appropriate byte in the vglKeyStatus[] array.
- *****************************************************************************/
- void interrupt int9( void )
- {
- register i;
- unsigned char al, ah, c;
-
- c = inportb( 0x60 ); /* Get the scan code */
- for( i = 0; i < VGL_NUMKEYS; i++ ) /* Loop through the table */
- {
- if( c == Keys[i].downcode ) /* Is it a downcode? */
- {
- ACKKEY; /* Acknowledge the keystroke */
- vglKeyStatus[i] = 1; /* Set the status byte to 1 */
- break; /* We're done! */
- }
- if( c == Keys[i].upcode ) /* Is it an upcode? */
- {
- ACKKEY; /* Acknowledge the keystroke */
- vglKeyStatus[i] = 0; /* Reset the status byte to 0 */
- break; /* We're done! */
- }
- }
- if( i == VGL_NUMKEYS ) /* Otherwise, we call the original */
- _chain_intr( oldint9 ); /* int 9 handler */
- }
-
- /*****************************************************************************
- Called to start the trapping of keys. The current status of the NumLock
- key is preserved, then NumLock is turned off. Don't forget to call
- vglReleaseKeys() before your program exits!
- *****************************************************************************/
- vglTrapKeys()
- {
- int i;
-
- for( i = 0; i < VGL_NUMKEYS; i++ ) /* Initialize the status bytes */
- vglKeyStatus[i] = 0;
-
- NumLock = (*kbdata & 32) == 32; /* Save the current numlock status */
-
- *kbdata &= (255-32); /* Turn off numlock */
-
- oldint9 = getvect( 0x09 ); /* Save the current int 9 handler */
- oldint1b = getvect( 0x1b );
- oldint23 = getvect( 0x23 );
-
- setvect( 0x09, int9 ); /* Install out int 9 handler */
- setvect( 0x1b, int1b );
- setvect( 0x23, int23 );
- return;
- }
-
- /*****************************************************************************
- Stops the trapping of keys. NumLock is restored to its previous value.
- IMPORTANT!!! If you previously called vglTrapKeys(), you **MUST** call
- this routine before exiting your program or evil things may happen!
- *****************************************************************************/
- vglReleaseKeys()
- {
- setvect( 0x09, oldint9 ); /* Restore the old int 9 handler */
- setvect( 0x1b, oldint1b );
- setvect( 0x23, oldint23 );
-
- if( NumLock ) /* Restore the numlock status */
- *kbdata |= 32;
- return;
- }
-
-